<template>
	<div class="upload-thumb">
		<Alert style="max-width:300px;">
			<slot name="remind">图片尺寸 {{size.width}}px<span style="margin: 0 2px;">*</span>{{size.height}}px </slot>
		</Alert>
		<vuedraggable :list="uploadList" :disabled="!draggable||!multiple" :animation="200" class="list-group" ghost-class="thumb-ghost"
		 @end="onEnd">
			<div class="upload-list" :style="{width: width, height: height, lineHeight: height}" v-for="(item, index) in uploadList"
			 :key="index">
				<div v-if="item.status == 'finished'">
					<img :src="item.url" :style="{height: height}" />
					<div class="upload-list-cover">
						<Icon type="ios-eye-outline" @click="handleView(item.url)"></Icon>
						<Icon type="ios-trash-outline" @click="handleRemove(item)"></Icon>
					</div>
				</div>
				<div v-else>
					<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
				</div>
			</div>
		</vuedraggable>

		<template v-if="limit>uploadList.length">
			<div class="upload-btn ivu-upload" :style="{width: width}">
				<div class="ivu-upload ivu-upload-drag">
					<div class="upload-camera" :style="{width: width, height: height, lineHeight: height}" @click="inputBtn">
						<Icon type="md-camera" size="20"></Icon>
					</div>
					<input style="display: none" type="file" accept="image/*" name="file" ref="getImageInput" @change="getImageInput">
				</div>
			</div>
		</template>

		<Modal title="图片裁剪" v-model="cropperModal" :styles="{top: '30px',padding:'0px 50px'}" draggable :width="(modalWidth>600?modalWidth:modalWidth+previews.w)+30" >
			<Alert >
				<slot  name="remind">图片尺寸 {{size.width}}px<span style="margin: 0 2px;">*</span>{{size.height}}px </slot>
				<span>您可以通过滑动鼠标中轴来进行图片缩放调整</span>
			</Alert>
			<Row>
				<Col :span="modalWidth>600?24:14">
					<vueCropper :style="{width: size.width/size.enlarge+'px', height: size.height/size.enlarge+'px'}" ref="cropper" :img="option.img"
					 :outputType="option.outputType" autoCrop :full="false" :original="false" :centerBox="false" :fixedBox="true" fixed
					 :autoCropWidth="size.width/size.enlarge" :autoCropHeight="size.height/size.enlarge" mode="100% auto" :fixedNumber="[size.width/size.enlarge,size.height/size.enlarge]"
					 :enlarge="size.enlarge" @realTime="realTime"></vueCropper>
				</Col>
				<Col  :span="modalWidth>600?24:10">
					<p>预览图片</p>
					<div :style="previewStyle">
						<div :style="previews.div">
							<img :src="previews.url" :style="previews.img" />
						</div>
					</div>
				</Col>
			</Row>
			
			<div slot="footer">
				<Button type="text" @click="cropperModal=false">取消</Button>
				<Button type="primary" :loading="uploadLoading" @click="upload" icon="ios-cloud-upload-outline">上传裁剪后的图片</Button>
			</div>
		</Modal>

		<Modal title="图片预览" v-model="viewImage" :styles="{top: '30px'}" draggable>
			<img :src="imgUrl" alt="无效的图片链接" style="width: 100%;margin: 0 auto;display: block;">
			<div slot="footer">
				<Button @click="viewImage=false">关闭</Button>
			</div>
		</Modal>
	</div>
</template>

<script>
	//https://github.com/xyxiao001/vue-cropper
	import {
		uploadFile,
		base64Upload
	} from "@/api/index";
	import vuedraggable from "vuedraggable";
	import {
		VueCropper
	} from "vue-cropper";

	export default {
		name: "uploadPicThumbCropper",
		components: {
			VueCropper,
			vuedraggable
		},
		props: {
			value: {},
			draggable: {
				type: Boolean,
				default: true
			},

			multiple: {
				type: Boolean,
				default: true
			},
			maxSize: {
				type: Number,
				default: 5
			},

			limit: {
				type: Number,
				default: 10
			},
			width: {
				type: String,
				default: "60px"
			},
			height: {
				type: String,
				default: "60px"
			},
			data: {
				type: Object,
				default: null,
			},

			size: {
				type: Object,
				default: () => {
					return {
						width: 200,
						height: 200,
						enlarge: 1, //图片根据截图框输出比例倍数
					}
				},
			},

		},
		computed: {
		    modalWidth() {
		        return Math.max(this.size.width/this.size.enlarge,this.minWidth);
		    },
			
		},
		data() {
			return {
				cropperModal: false,
				option: {
					img: '',
					outputType: "png"
				},
				minWidth:400,
				previews: {w:0},
				previewStyle: {},
				uploadLoading: false,
				uploadList: [],
				viewImage: false,
				imgUrl: ""
			};
		},
		methods: {
			onEnd() {
				this.returnValue();
			},
			inputBtn() {
				this.$refs.getImageInput.click();
			},
			getImageInput() {
				let that = this;
				//这里是为了选择图片的时候又取消了选择，导致返回空的情况，需要设置一下，不然会导致错误情况
				if (this.$refs.getImageInput.value != "") {
					if (this.handleBeforeUpload()) {
						let inputFile = this.$refs.getImageInput.files[0];
						let reader = new FileReader();
						reader.readAsDataURL(inputFile);
						reader.onload = function(event) {
							// vm.imageList = event.target.result; 两种写法相同
							//vm.imageList.push(reader.result);
							that.option.img = reader.result;
							that.cropperModal = true;
						};

						this.$refs.getImageInput.value = "";

					}

				}
			},

			init() {
				this.setData(this.value, true);
			},
			handleBeforeUpload() {
				if (this.multiple && this.uploadList.length >= this.limit) {
					this.$Message.warning("最多只能上传" + this.limit + "张图片");

					return false;
				}
				return true;
			},
			handleView(imgUrl) {
				this.imgUrl = imgUrl;
				this.viewImage = true;
			},
			handleRemove(file) {
				const uploadList = this.uploadList;
				this.uploadList.splice(uploadList.indexOf(file), 1);
				this.returnValue();
			},
			returnValue() {
				if (!this.uploadList || this.uploadList.length < 1) {
					if (!this.multiple) {
						this.$emit("input", "");
						this.$emit("on-change", "");
					} else {
						this.$emit("input", []);
						this.$emit("on-change", []);
					}
					return;
				}
				if (!this.multiple) {
					// 单张
					let v = this.uploadList[0].url;
					this.$emit("input", v);
					this.$emit("on-change", v);
				} else {
					let v = [];
					this.uploadList.forEach(e => {
						v.push(e.url);
					});
					this.$emit("input", v);
					this.$emit("on-change", v);
				}
			},
			setData(v, init) {
				if (typeof v == "string") {
					// 单张
					if (this.multiple) {
						this.$Message.warning("多张上传仅支持数组数据类型");
						return;
					}
					if (!v) {
						this.uploadList = [];
						return;
					}

					this.uploadList = [];
					let item = {
						url: v,
						status: "finished"
					};
					this.uploadList.push(item);
					this.$emit("on-change", v);
				} else if (typeof v == "object") {
					// 多张
					if (!this.multiple) {
						this.$Message.warning("单张上传仅支持字符串数据类型");
						return;
					}
					this.uploadList = [];
					if (v.length > this.limit) {
						for (let i = 0; i < this.limit; i++) {
							let item = {
								url: v[i],
								status: "finished"
							};
							this.uploadList.push(item);
						}
						this.$emit("on-change", v.slice(0, this.limit));
						if (init) {
							this.$emit("input", v.slice(0, this.limit));
						}
						this.$Message.warning("最多只能上传" + this.limit + "张图片");
					} else {
						v.forEach(e => {
							let item = {
								url: e,
								status: "finished"
							};
							this.uploadList.push(item);
						});
						this.$emit("on-change", v);
					}

				}

			},
			// 实时预览
			realTime(data) {
				let preview = data,
					h = 0.5;
				this.previewStyle = {
					width: preview.w + "px",
					height: preview.h + "px",
					overflow: "hidden",
					margin: "0",
					zoom: h
				};
				this.previews = data;
			},
			upload() {
				// 获取截图的base64 数据
				this.$refs.cropper.getCropData(data => {
					this.uploadLoading = true;
					base64Upload({
						base64: data
					}).then(res => {
						this.uploadLoading = false;
						if (res.success) {
							let f = {
								status: 'finished',
								url: res.result
							}
							//单张图片处理
							if (!this.multiple && this.uploadList.length > 0) {
								// 清空数组
								this.uploadList.splice(0, this.uploadList.length);
							}
							this.uploadList.push(f);
							// 返回组件值
							this.returnValue();
							this.$Message.success("上传成功");
							this.cropperModal = false;

						} else {
							this.$Message.error(res.message);
						}
					});
				});
			}
		},
		mounted() {
			this.init();
		},
		watch: {
			value(val) {
				this.setData(val);
			}
		},

	};
</script>

<style lang="less">
	.upload-thumb {
		width: 100%;
		.upload-list {
			display: inline-block;
			text-align: center;
			border: 1px solid transparent;
			border-radius: 4px;
			overflow: hidden;
			background: #fff;
			position: relative;
			box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
			margin-right: 5px;
		}

		.upload-list img {
			object-fit: cover;
		}

		.upload-btn {
			display: inline-block;
		}

		.upload-list-cover {
			display: none;
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			background: rgba(0, 0, 0, 0.6);
		}

		.upload-list:hover .upload-list-cover {
			display: block;
		}

		.upload-list-cover i {
			color: #fff;
			font-size: 20px;
			cursor: pointer;
			margin: 0 2px;
		}

		.list-group {
			display: inline-block;
		}

		.thumb-ghost {
			opacity: 0.5;
			background: #c8ebfb;
		}
	}
	
</style>
